﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using HslCommunication.Core.Net;
using Newtonsoft.Json;
namespace Net_SCADA
{
    public class MultipleLanguage
    {
        //语言的索引
        public static int systemLanguageIndex { get; set; } = 0;//0 是第一语言
        public static List<string> systemLanguageName { get; set; } = new List<string>() {"中文"};
        //信息提示内容
        public static List<MessageInfo> messageInfos { get; set; }=new List<MessageInfo>();
        //界面显示多语言内容
        public static Dictionary<string, List< ctrl>> formLanguage { get; set; }=new Dictionary<string, List<ctrl>>();
        public static void loadMessageInfos()
        {
            DataTable dt = DBOperate.getMessageInfos();
            if (dt == null) return;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                messageInfos.Add(new MessageInfo()
                {
                    msgTitle = dt.Rows[i]["title"].ToString().Split(';'),
                    msgContent = dt.Rows[i]["content"].ToString().Split(';'),
                    subContent = dt.Rows[i]["subcontent"].ToString().Split(';'),
                    msgButtons = Convert.ToInt32(dt.Rows[i]["buttons"]),
                    msgIndex = Convert.ToInt32(dt.Rows[i]["msgindex"])
                }) ;
            }
        }


        //在软件启动的时候，需要对界面的语言设置进行加载。保存相关的JSON字符串在字典里面
        public static void loadFormLanguageSetting()
        {
            Assembly a = Assembly.LoadFile(Application.ExecutablePath);
            Type[] types = a.GetTypes();
            foreach (Type t in types)
            {
                if (t.BaseType.Name == "Form" || t.BaseType.Name == "fdBaseForm") //遍历窗体
                {
                    if (formLanguage.ContainsKey(t.Name)) continue;
                    string s = loadLanguageSet(t.Name);
                    //根据json字符串，转换为需要的设置的对象数组s
                    if (string.IsNullOrEmpty(s)) 
                        formLanguage[t.Name]=new List<ctrl>();
                    else
                        formLanguage[t.Name] = JsonConvert.DeserializeObject<ctrl[]>(s).ToList();
                }
            }
        }   


        //在切换的时候，需要对 form_top 和 form_setting进行语言的切换
        //其他界面的语言切换在formactived中进行。每个form需要增加一个当前语言的变量 默认为 -1，
        public static void switchLanguage()
        {
            foreach (Form form in Application.OpenForms)//遍历打开的form ，设置界面语言
            {
                if (formLanguage.ContainsKey(form.Name))
                {
                    setLanguage(form, formLanguage[form.Name], systemLanguageIndex);
                }
            }
            saveLastFormLanguageIndex();
        }
        public static void switchLanguage(Form frm)
        {
            if (formLanguage.ContainsKey(frm.Name))
            {
                setLanguage(frm, formLanguage[frm.Name], systemLanguageIndex);
            }
        }

        //系统加载的时候，获取索引号，语言的名称
        public static void loadLastFormLanguageSet()
        {
            Ini ini = new Ini (@".\settings\setting.dat");
            //获取上次保存的索引号
            string v="0" + ini.ReadValue("Interface", "LanguageIndex");
            if (int.TryParse(v, out int x))
                systemLanguageIndex = x;
            //获取系统配置语言的顺序，各个语言用分号;进行分隔
            v = ini.ReadValue("Interface", "LanguageName").Trim();
            if (string.IsNullOrEmpty(v)) return;
            //因为setting.dat文件以UTF8的格式保存的，需要进行转换才能正确显示中文
            systemLanguageName = getStringFromUTF8(v).Split(';').ToList();
        }
        //在切换语言的时，保存最近语言的索引号
        public static void saveLastFormLanguageIndex()
        {
            Ini ini = new Ini(@".\settings\setting.dat");
            ini.Write("Interface", "LanguageIndex", systemLanguageIndex.ToString());
        }
        public static string getStringFromUTF8(string utf8String)
        {
            byte[] buffer1 = Encoding.Default.GetBytes(utf8String);
            byte[] buffer2 = Encoding.Convert(Encoding.UTF8, Encoding.Default, buffer1, 0, buffer1.Length);
            string strBuffer = Encoding.Default.GetString(buffer2, 0, buffer2.Length);
            return strBuffer;
        }

        public static void setLanguage(Form frm, List<ctrl> ctrls, int languageIndex)
        {
            //简单判断一下，减少错误的调用
            if (frm == null || ctrls==null || ctrls.Count==0) return;
            for (int i = 0; i < ctrls.Count; i++)
            {
                Control[] ctl = frm.Controls.Find(ctrls[i].Name, true);
                if (ctl != null)
                {
                    foreach (var item in ctl)
                    {
                        switch (item.GetType().Name)
                        {
                            //控件为DataGridview的column
                            case "DataGridView":
                                //使用对应的类型实例化反射出来的对象
                                DataGridView dv = item as DataGridView;
                                foreach (var languageTextItem in ctrls[i].Texts)
                                {
                                    if (dv.Columns.Contains(languageTextItem.Item))
                                    {
                                        dv.Columns[languageTextItem.Item].HeaderText = languageTextItem.language[languageIndex].content;
                                        dv.ColumnHeadersDefaultCellStyle.Font = languageTextItem.language[languageIndex].getFont();
                                    }
                                }
                                break;
                            //一个自定义的控件，用来显示参数的，只有的Title的属性显示标题
                            case "fdCtrZone":
                            //这里可以放置windows下的通用控件，控件都是以Text属性显示文本内容的。
                            case "Label"://text的都可以在这里设置
                            case "Button":
                            case "GroupBox":     //。。。。。。。
                                foreach (var languageTextItem in ctrls[i].Texts)
                                {
                                    if (languageTextItem.Item == "Text")
                                    {
                                        item.Text = languageTextItem.language[languageIndex].content;
                                        item.Font = languageTextItem.language[languageIndex].getFont();
                                    }
                                }
                                break;
                            
                            default:
                                break;
                        }
                    }
                }
            }

        }
        //private static void setLanguage(Form frm, FieldInfo ctrlInfo,ctrl languageCtrl,int languageIndex)
        //{
        //    //判断是否找到，并且能判断出修改的类型，这里好像也不需要判断
        //    if (ctrlInfo != null && ctrlInfo.FieldType.Name == languageCtrl.Type)
        //    {
        //        //根据找打对象的控件类型，进行相关控件的修改。这里没有使用ctrls[i].Type，是因为可能输入错误
        //        switch (ctrlInfo.FieldType.Name)
        //        {
        //            //控件为DataGridview的column
        //            case "DataGridViewTextBoxColumn":
        //                //使用对应的类型实例化反射出来的对象
        //                DataGridViewTextBoxColumn col = (DataGridViewTextBoxColumn)ctrlInfo.GetValue(frm);
        //                //根据需要设置的属性，查找配置对象
        //                languageSet v = getLanguageString(languageCtrl.Texts, "HeaderText", languageIndex);
        //                if (v != null)//做简单的判断
        //                {
        //                    //设置文本内容
        //                    col.HeaderText = v.content;
        //                    //设置字体，简单的可以用来防止显示不下的问题
        //                    col.DataGridView.ColumnHeadersDefaultCellStyle.Font = v.contentFont;
        //                }
        //                break;
        //            //这里可以放置windows下的通用控件，控件都是以Text属性显示文本内容的。
        //            case "fdCtrZone":
        //            case "Label"://text的都可以在这里设置
        //            case "Button":
        //            case "CheckBox":
        //            case "GroupBox":     //。。。。。。。
        //                Control ctrl = (Control)ctrlInfo.GetValue(frm);
        //                v = getLanguageString(languageCtrl.Texts, "Text", languageIndex);
        //                if (v != null)
        //                {
        //                    ctrl.Text = v.content;
        //                    Font ft = v.contentFont;
        //                    if (ft != null)
        //                        ctrl.Font = ft;
        //                }
        //                break;
        //            default:
        //                break;
        //        }
        //    }
        //}
     

       

        /// <summary>
        /// 根据条件对象找到需要显示的语言对象，本函数应该可以省略
        /// </summary>
        /// <param name="txt">所有配置的语言对象的list</param>
        /// <param name="textAttribute">需要修改属性的名称</param>
        /// <param name="languageIndex">语言索引号，数组的下标</param>
        /// <returns>返回语言对象</returns>
        private static languageSet getLanguageString(List<languageText> txt, string textAttribute, int languageIndex)
        {

            //在list中找到需要设置的属性对象
            languageText t = txt.Find(x => x.Item == textAttribute);
            if (t != null)
            {
                return t.language[languageIndex];//返回找到的对象
            }
            return null;
        }
        /// <summary>
        /// 加载语言配置文件
        /// </summary>
        /// <param name="controlName">Form的Name</param>
        /// <returns>json格式的字符串</returns>
        public static string loadLanguageSet(string controlName)
        {
            string jsonFilePath = $@".\settings\language\{controlName}.json";

            // 使用 File.Exists 检查文件是否存在
            if (File.Exists(jsonFilePath))
            {
                try
                {
                    // 读取文件内容
                    string jsonFileContent = File.ReadAllText(jsonFilePath);
                    return jsonFileContent;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex.Message);
                }
            }
            else
            {
                Console.WriteLine($"{controlName}'s File not found.");
            }
            return null;
        }
        
        public static ctrl getLanguageCtrl(string name, string type, string item, string[] languageTexts, string subText, string[] font)
        {
            FontConverter converter = new FontConverter();
            Font[] ft = new Font[font.Length];
            for (int i = 0; i < font.Length; i++)
                ft[i]= converter.ConvertFromString(font[i]) as Font;
            return getLanguageCtrl(name, type, item, languageTexts, subText, ft);
        }
        public static ctrl getLanguageCtrl(string name, string type, string item, string[] languageTexts, string subText, Font[] font)
        {
            languageSet[] languageSets = new languageSet[languageTexts.Length];
            for (int i = 0; i < languageTexts.Length; i++)
            {
                languageSets[i] = new languageSet()
                {
                    content = $"{languageTexts[i]} {subText}",
                    contentFont = font[i]
                };
            }
            List<languageText> texts = new List<languageText>
                {
                    new languageText() { language = languageSets,Item=item  }
                };
            return (new ctrl()
            {
                Name = name,
                Type = type,
                Texts = texts
            });
        }
        public static ctrl getLanguageCtrl(string name, string type, string item, string[] languageTexts, string subText, string font)
        {
            FontConverter converter = new FontConverter();
            Font ft= converter.ConvertFromString(font) as Font;
            return getLanguageCtrl(name, type, item, languageTexts, subText, ft);
        }
        public static ctrl getLanguageCtrl(string name, string type, string item, string[] languageTexts, string subText, Font font)
        {
            Font[] ft = new Font[languageTexts.Length];
            for (int i = 0; i < ft.Length; i++) ft[i] = font;
            return getLanguageCtrl(name, type, item, languageTexts, subText, ft);
        }
    }


    public class ctrl
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public List<languageText> Texts { get; set; }

        public static explicit operator Label(ctrl v)
        {
            throw new NotImplementedException();
        }
    }

    public class languageText
    {
        public string Item { get; set; } = "Text";
        public languageSet[] language { get; set; }
    }
    public class languageSet
    {
        private Font _contentFont;
        private string _font;
        public string content { get; set; }
        public string font { get { return _font; } set { _font = value; _contentFont = getFont(); } }
        public Font contentFont { get { return _contentFont; } set { _contentFont = value; _font = getFontString(value); } }
        public Font getFont()
        {
            FontConverter converter = new FontConverter();
            return converter.ConvertFromString(_font) as Font;
        }
        private string getFontString(Font ft)
        {
            FontConverter converter = new FontConverter();
            return converter.ConvertToString(ft);
        }
    }


}
